// @ts-ignore
import axios from 'axios'
import * as step from '@flow-step/step-toolkit'
import * as path from 'path'
import * as os from 'os'
import * as redline from './redline'
import { execSync } from 'child_process';
import { exec as originalExec } from 'child_process';
import { promisify } from 'util';
import { mkdir,readFile } from 'fs/promises';
const exec = promisify(originalExec);
import process from "process";
import {platform} from "@flow-step/step-toolkit";
export const SEP = path.sep
export const EOL = os.EOL
export async function createDirectory(directoryPath: string): Promise<void> {
        // 使用 recursive 选项创建目录和任何必要的上级目录
    await mkdir(directoryPath, { recursive: true });
}

export function executeCmdSync(executeCmd: string, args: string[] = []) {
    try {
        const output = execSync(`${executeCmd} ${args.join(' ')}`, { encoding: 'utf-8' });
        // 如果 execSync 执行成功，它将把命令的 stdout 作为字符串返回
        step.info(output);
    } catch (error) {
        // 如果 execSync 抛出错误，error 将带有 stderr 属性
        step.error("executeCmdSync error "+error);
        process.exit(1);
    }
}


interface Vulnerability {
    Severity: string;
}

interface Summary {
    severity: string;
    count: number;
}

export async function summarizeVulnerabilities(reportPath: string ): Promise<void> {
    try {
        // 读取 JSON 报告文件
        const data = await readFile(reportPath, 'utf-8');
        const report = JSON.parse(data);

        // 处理报告数据
        const flattenVulns: Vulnerability[] = (report.Results || [])
            .map((result: any) => result.Vulnerabilities || [])
            .flat();

        const groupedBySeverity = Object.values(flattenVulns.reduce((acc: {[key: string]: Vulnerability[]}, vuln: Vulnerability) => {
            (acc[vuln.Severity] = acc[vuln.Severity] || []).push(vuln);
            return acc;
        }, {}));

        const summary: Summary[] = groupedBySeverity.map((group: Vulnerability[]) => ({
            severity: group[0].Severity,
            count: group.length,
        }));

        // 累计总计数
        let totalCnt = summary.reduce((acc, item) => acc + item.count, 0);

        // 针对各个级别的计数
        const countsBySeverity = (severity: string) => {
            const found = summary.find(item => item.severity === severity);
            return found ? found.count : 0;
        };

        let criticalCnt = countsBySeverity('CRITICAL');
        let highCnt = countsBySeverity('HIGH');
        let mediumCnt = countsBySeverity('MEDIUM');

        // 输出结果
        step.info('总计:'+ totalCnt);
        step.info('CRITICAL:'+ criticalCnt);
        step.info('HIGH:'+ highCnt);
        step.info('MEDIUM:'+ mediumCnt);
        if(!totalCnt){
            totalCnt=0
            criticalCnt=0
            highCnt=0
            mediumCnt=0
        }
        let outputTitle = `[${process.env['stepIdentifier']}]STAT_INFO_TITLE:Trivy镜像扫描`;
        step.addOutput( outputTitle)
        step.info(outputTitle)

        redline.redlineCheck('total','全部',totalCnt,'Error')
        redline.redlineCheck('critical','严重',criticalCnt,'Error')
        redline.redlineCheck('high','高',highCnt,'Warning')
        redline.redlineCheck('medium','中',mediumCnt,'Warning')

    } catch (error) {
        console.error('处理 JSON 报告时出错:', error);
    }
}

export async function getEndpoint() {
    let endpoint =
        process.env['ENDPOINT'] || 'oss-cn-beijing-internal.aliyuncs.com'
    if (process.env['ENDPOINT'] != undefined) {
        return endpoint
    }
    let config = {
        method: 'get',
        url: 'oss-cn-beijing-internal.aliyuncs.com',
        timeout: 1000,
        headers: {}
    }
    await axios(config)
        .then(function (response: {data: any}) {
            endpoint = 'oss-cn-beijing-internal.aliyuncs.com'
        })
        .catch(function (err: any) {
            endpoint = 'oss-cn-beijing.aliyuncs.com'
        })
    return endpoint
}

export async function installTrivy(): Promise<string> {
    let toolName: string = 'trivy'
    let version: string = "1.1"



    let suffix = "windows" == platform.getPlatform()?"zip":"tar.gz";
    step.info(`Going to install the trivy with version ${version} suffix ${suffix}`)
    const cachedpath = await step.tool.install(toolName, version, suffix)
    step.info("install trivy success,path:"+cachedpath)
    return cachedpath
}
